package com.tbit.main.service.impl;

import cn.hutool.core.util.StrUtil;
import com.tbit.common.constant.OperationPlatform;
import com.tbit.common.constant.MannedStatusEnum;
import com.tbit.common.entity.MachineOpLog;
import com.tbit.common.utils.MACUtils;
import com.tbit.main.constant.ControlTypeConstant;
import com.tbit.main.controller.interceptor.LoginUserContextHolder;
import com.tbit.main.dao.core.MannedDao;
import com.tbit.main.exception.BaseException;
import com.tbit.main.pojo.AccountUser;
import com.tbit.main.pojo.Machine;
import com.tbit.main.pojo.Manned;
import com.tbit.main.service.DataService;
import com.tbit.main.service.MannedService;
import com.tbit.main.util.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

/**
 * @author LMY
 * @create 2023-05-25 17:05
 */
@Service
public class MannedServiceImpl implements MannedService {

    @Autowired
    private MannedDao mannedDao;
    @Autowired
    private DataService dataService;
    @Autowired
    private MachineOpLogService machineOpLogService;

    @Override
    public void createOrUpdate(Machine machine, String mannedNO, String serNo) {
        AccountUser loginUser = LoginUserContextHolder.getLoginUser();

        boolean blank = StrUtil.isBlank(mannedNO);

        if (MACUtils.isMac(mannedNO)) {
            mannedNO = MACUtils.getCodeFromMac(mannedNO);
        }

        Manned manned = new Manned();
        manned.setAccountId(machine.getAccountId());
        manned.setMachineId(machine.getMachineId());
        manned.setMachineNO(machine.getMachineNO());
        manned.setMannedNO(mannedNO);
        manned.setMannedMac(MACUtils.getMacFromCode(blank ? "0" : mannedNO));
        manned.setCreateTime(DateTimeUtil.getNowTime());
        manned.setUpdateTime(DateTimeUtil.getNowTime());
        manned.setCreator(loginUser.getName());
        manned.setUpdater(loginUser.getName());
        manned.setSerNo(serNo);
        manned.setStatus(blank ? MannedStatusEnum.UNBIND.getStatus() : MannedStatusEnum.BIND.getStatus());

        Manned mannedDb = getOne(machine.getMachineId());
        if (mannedDb != null) {
            mannedDao.update(manned);
        } else {
            if (blank) {
                throw new BaseException("该设备未绑定，请先绑定再解绑");
            }
            mannedDao.add(manned);
        }

        // 插入车辆操作日志
        String detail = blank ?
                "载人设备编号: " + mannedDb.getMannedNO() :
                "载人设备编号: " + mannedNO;
        machineOpLogService.insertSingle(MachineOpLog.builder()
                .accountId(machine.getAccountId())
                .machineId(machine.getMachineId())
                .machineNO(machine.getMachineNO())
                .userCode(machine.getUserCode())
                .operation("载人设备")
                .opType(blank ? "解绑" : "绑定")
                .opUser(loginUser.getName())
                .opUserPhone(loginUser.getPhone())
                .opPlatform(OperationPlatform.MAINTAIN.code)
                .result(true)
                .opTime(LocalDateTime.now())
                .detail(detail)
                .build());
    }

    @Override
    public void del(String machineNO) {
        mannedDao.del(machineNO);
    }

    @Override
    public List<Manned> getAccountId(Integer accountId) {
        return mannedDao.getAccountId(accountId);
    }

    @Override
    public Manned getOne(Integer machineId) {
        if (machineId == null) {
            throw new BaseException("Machine.control.paramName.notNull");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("machineId", machineId);
        return mannedDao.getOne(map);
    }

    @Override
    public List<Manned> getAll() {
        return mannedDao.getAll();
    }

    @Override
    public void update(String machineNO, String mannedNO) {
        Integer machineId = dataService.getMachineId(machineNO);
        Integer accountId = dataService.getAccountId(machineNO);
        Manned manned = new Manned();
        manned.setAccountId(accountId);
        manned.setMachineId(machineId);
        manned.setMachineNO(machineNO);
        manned.setMannedNO(mannedNO);
        manned.setCreateTime(DateTimeUtil.getNowTime());
        mannedDao.update(manned);
    }

    @Override
    public void updateIfPresent(String serNo, String paramRet) {
        if (mannedDao.countBySerNo(serNo) > 0 && StrUtil.isNotBlank(paramRet)) {
            // 绑定状态（0：未绑定，1：绑定，2：绑定中，3：绑定失败，4：解绑，5：解绑中，6：解绑失败）
            Manned manned = new Manned();
            manned.setSerNo(serNo);
            // 成功
            if ((ControlTypeConstant.MANNED_BOUND + "=" + ControlTypeConstant.CONTROL_TYPE_OK).toUpperCase(Locale.ROOT)
                    .equals(paramRet.toUpperCase(Locale.ROOT))) {
                manned.setStatus(-1);
            }
            // 失败
            else {
                manned.setStatus(1);
            }
            mannedDao.updateBySerNo(manned);
        }
    }

    @Override
    public void checkExistThrow(String mannedNO) {
        if (StrUtil.isBlank(mannedNO)) {
            return;
        }

        if (MACUtils.isMac(mannedNO)) {
            mannedNO = MACUtils.getCodeFromMac(mannedNO);
        }

        List<Manned> list = mannedDao.selectListByMannedNo(mannedNO);
        // 使用最新的比较
        Manned manned = list.stream().max(Comparator.comparing(Manned::getUpdateTime)).orElse(null);
        if (Objects.nonNull(manned)
                && (manned.getStatus().equals(MannedStatusEnum.BIND.getStatus()) || manned.getStatus().equals(MannedStatusEnum.BINDING.getStatus()))) {
            throw new BaseException("该载人设备已被绑定或正在绑定，请先解绑");
        }
    }
}
